#include <sys/device.h>
#include <io.h>
#include <sys/timer.h>
#include "adc.h"
#define set_bit(sfr,bit)	(sfr |= _BV(bit))
#define clear_bit(sfr,bit)	(sfr &= ~(_BV(bit)))
static void inline Set_Channel( unsigned char channel);
//unsigned long long aintegr[2];

void  ADC_Init(void)
{
  ADCSR = (1<< ADEN)|(0<<ADRF) |(0<<ADIE) |(0<<ADSC)|(0<<ADIF)|(1<<ADPS2)|(0<<ADPS1)|(1<<ADPS0);  //ADC enable, prescaler = 128
  ADMUX = (0<<REFS1)|(0<<REFS0)|(0<<ADLAR)|(0<<MUX4)|(0<<MUX3)|(0<<MUX2) |(0<<MUX1) |(0<<MUX0 );  //internal reference, left ended result
}

static void inline Set_Channel( unsigned char channel)
{
   channel = channel&0x1f;        
   ADMUX = (0<<REFS1)|(0<<REFS0)|(0<<ADLAR)|(0<<MUX4)|(0<<MUX3)|(0<<MUX2) |(0<<MUX1) |(0<<MUX0 );
   ADMUX = ADMUX|channel;
   NutDelay(1);
}
   
int ADC_M(void)
{
  unsigned int result = 0;
  unsigned char  result1 = 0, result2 =0;
  unsigned int nTry = 50000;

   set_bit(ADCSR, ADSC);   //start conversion;
   while( (ADCSR&0x40) == 0);
   while( (ADCSR&(1<<ADSC))>0 ) //wait for completion
   {
       if(--nTry == 0)
       {
         return(-1000);
       }
    }
    result1 = ADCL;
    result2  =ADCH;
    result = ((unsigned int)result2<<8) + result1;
    return ((int)result);
 }     

int ADC_Measure(unsigned char channel)
{
  unsigned int result = 0;
  unsigned char  result1 = 0, result2 =0;
  unsigned int nTry = 50000;
   channel = channel&0x1f;        
   ADMUX = (0<<REFS1)|(0<<REFS0)|(0<<ADLAR)|(0<<MUX4)|(0<<MUX3)|(0<<MUX2) |(0<<MUX1) |(0<<MUX0 );
   ADMUX = ADMUX|channel;
   NutSleep(1);
   set_bit(ADCSR, ADSC);   //start conversion;
   while( (ADCSR&0x40) == 0);
   while( (ADCSR&(1<<ADSC))>0 ) //wait for completion
   {
       if(--nTry == 0)
       {
         return(-1000);
       }
    }
    result1 = ADCL;
    result2  =ADCH;
    result = ((unsigned int)result2<<8) + result1;
//    result = ((unsigned long)result)*625/256;   //get voltage                     
	result = (((unsigned long)result)*5208)>>8; // (2500/1024)*1000/120 ~= 5208/256 
    return ((int)result);
 } 

int ADC_Measure_Mean(unsigned char channel)
{
  unsigned char i = 0;
  unsigned int result = 0;
  Set_Channel(channel);
  for(i = 0; i<8; i++)
  {
	result+=ADC_M();
  }
  result = result/8;
  result = (((unsigned long)result)*5208)>>8; // (2500/1024)*1000/120 ~= 5208/256 
  return(result);
}
